package com.infocollect.project.api.helper;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class ReflectHelper {
    /**
     * 判断对象或对象数组中每一个对象是否为空: 对象为null，字符序列长度为0，集合类、Map为empty
     *
     * @param obj
     * @return
     */
    private  static  boolean isNullOrEmpty(Object obj) {
        if (obj == null)
            return true;

        if (obj instanceof CharSequence)
            return ((CharSequence) obj).length() == 0;

        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();

        if (obj instanceof Map)
            return ((Map) obj).isEmpty();

        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {
                return true;
            }
            boolean empty = true;
            for (int i = 0; i < object.length; i++) {
                if (!isNullOrEmpty(object[i])) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }

        return false;
    }
    /***
     * Get Specified Field
     *
     * @param clazz
     * @param fieldName
     * @return
     */
    public static Field getSpecifiedField(Class<?> clazz, String fieldName) {
        Field f = null;
        if (isNullOrEmpty(clazz)) {
            return null;
        }
        try {
            f = clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            return getSpecifiedField(clazz.getSuperclass()/*
             * may be null if it is
             * Object .
             */, fieldName);
            // e.printStackTrace();
        }
        return f;
    }
    /***
     * get all field ,including fields in father/super class
     *
     * @param clazz
     * @return
     */
    public static List<Field> getAllFieldList(Class<?> clazz) {
        List<Field> fieldsList = new ArrayList<>();// return object
        if (clazz == null) {
            return null;
        }

        Class<?> superClass = clazz.getSuperclass();// father class
        if (!superClass.getName().equals(Object.class.getName()))/*
         * java.lang.Object
         */{

            // System.out.println("has father");
            fieldsList.addAll(getAllFieldList(superClass));// Recursive
        }
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            // 排除因实现Serializable 接口而产生的属性serialVersionUID
            if (!field.getName().equals("serialVersionUID")) {
                fieldsList.add(field);
            }
        }
        return fieldsList;
    }
    /***
     * 获取指定对象的属性值
     *
     * @param obj
     * @param name
     *            :Field
     * @return
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static Object getObjectValue(Object obj, Field name)
            throws SecurityException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException {

        // Field f = getSpecifiedField(obj.getClass(), name.getName());
        if (name == null) {
            System.out.println("[ReflectHWUtils.getObjectValue]"
                    + obj.getClass().getName() + " does not has field " + name);
            return null;
        }
        name.setAccessible(true);
        return name.get(obj);
    }
}
